/////////////////////////////////////////////////////////////////////////////
//
//  Fifteen Puzzle
//  Kolonitsky Developers Alliance (c) 2012
//  All rights received
//
/////////////////////////////////////////////////////////////////////////////

package view{

    import caurina.transitions.Tweener;

    import com.adobe.utils.ArrayUtil;

    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Matrix;
    import flash.text.TextField;

    import model.types.ApplicationStates;

    import model.vo.PuzzleVO;

    import view.states.PuzzleState;
    import view.states.IState;
    import view.states.InitializeState;
    import view.states.MenuState;
    import view.states.ResultState;
    import caurina.transitions.properties.FilterShortcuts;


    /**
     * Root display object. Game class create states and handle changes in
     * gameVO
     */
    public class Game extends Sprite
    {
        public function Game()
        {
            FilterShortcuts.init();

            states = [];
            states[ApplicationStates.GAME_MENU] = new MenuState();
            states[ApplicationStates.GAME_INITIALIZE] = new InitializeState();
            states[ApplicationStates.GAME_GAME] =  new PuzzleState();
            states[ApplicationStates.GAME_RESULT] = new ResultState();

            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        /**
         * UpdateGame is a part of game loop. This method render game with
         * different states. Each state render own graphics according game
         * state.
         *
         * @param game rendered game object
         */
        public function updateGame(game:PuzzleVO):void
        {
            if (currentStateId != game.state)
            {
                state = states[game.state] as IState;
                state.activate();

                stateTransition.changeState(currentStateId, game.state);

                currentStateId = game.state;
            }

            state.displayGame(game);
        }


        //-------------------------------------------------------------------
        //
        // Private
        //
        //-------------------------------------------------------------------

        private var state:IState = null;
        private var states:Array = null;
        private var currentStateId:uint = ApplicationStates.GAME_NONE;

        private var board:Bitmap = null;
        private var background:Bitmap = null;
        private var numbers:Vector.<Bitmap> = null;
        private var numberContainer:Sprite = null;

        private var stateTransition:StateTransition = null;

        private function addedToStageHandler(event:Event):void
        {
            stage.align = "TL";
            stage.scaleMode = "noScale";

            AppFacade.getInstance().startup(this);

            createChildren();

            for each(var state:IState in states)
            {
                state.numbers = numbers;
                state.skin.visible = false;
                addChild(state.skin);
            }

            stateTransition = new StateTransition();
            stateTransition.init(stage, numberContainer, states);
        }

        private function createChildren():void
        {
            if (background == null)
            {
                background = new ImageAssets.BACKGROUND_BITMAP();
                addChild(background);
            }

            if (board == null)
            {
                board = new ImageAssets.BOARD_BITMAP();
                board.x = Config.BOARD_LEFT - 4;
                board.y = Config.BOARD_TOP - 4;
            }

            if (numbers == null)
            {
                numberContainer = new Sprite();
                numberContainer.addChild(board)
                addChild(numberContainer);

                numbers = new Vector.<Bitmap>(Config.BOARD_CELLS);
                for (var i:int = 0; i < Config.BOARD_CELLS; i++)
                {
                    var xIndex:int = i % Config.BOARD_WIDTH;
                    var yIndex:int = (i - xIndex) / Config.BOARD_WIDTH;
                    var numberTile:Bitmap = createNumberTile(xIndex, yIndex);
                    numberTile.alpha = 0.0;
                    numbers[i] = numberTile;
                    numberContainer.addChild(numberTile);
                }
            }
        }

        private var numbersBitmap:Bitmap = null;

        private function createNumberTile(xIndex:int, yIndex:int):Bitmap
        {
            if (numbersBitmap == null)
                numbersBitmap = new ImageAssets.NUMBERS_BITMAP();

            var tileX:Number = xIndex * Config.TILE_WIDTH;
            var tileY:Number = yIndex * Config.TILE_HEIGHT;
            var translateMatrix:Matrix = new Matrix(1, 0, 0, 1, -tileX, -tileY);
            var tileBitmapData:BitmapData = new BitmapData(Config.TILE_WIDTH, Config.TILE_HEIGHT, true, 0xFF0000);
            tileBitmapData.draw(numbersBitmap, translateMatrix);

            var result:Bitmap = new Bitmap(tileBitmapData);
            return result;
        }
    }
}
